package com.example.canteen.service;

import com.example.canteen.converter.SetMealConverter;
import com.example.canteen.dao.*;
import com.example.canteen.dto.DishDTO;
import com.example.canteen.dto.SetMealDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SetMealServiceImpl implements SetMealService {
    @Autowired
    SetMealRepository setMealRepository;
    @Autowired
    CategoryRepository categoryRepository;
    @Autowired
    DishRepository dishRepository;

    @Override
    @Transactional
    public Long addSetMeal(SetMealDTO setMealDTO, String categoryName) {
        if (setMealRepository.findByName(setMealDTO.getName()) != null) {
            throw new IllegalArgumentException("setMeal already exists");
        }
        SetMeal setMeal = SetMealConverter.convertSetMeal(setMealDTO);
        Category category = categoryRepository.findByName(categoryName);
        setMeal.setCategory(category);
        setMealDTO.setId(setMealRepository.save(setMeal).getId());
        for (String dishName : setMealDTO.getDishCount().keySet()) {
            Dish dish = dishRepository.findByName(dishName);
            if (dish != null) {
                setMealRepository.insertSetMealDish(setMealDTO.getId(), dish.getId(), setMealDTO.getDishCount().get(dishName));
            }
        }
        return setMealDTO.getId();
    }

    @Override
    public Set<SetMealDTO> getAllSetMeals() {
        Set<SetMealDTO> setMealDTOs = new HashSet<>();
        for (SetMeal setMeal : setMealRepository.findAll()) {
            Map<String, Integer> dishCount = new HashMap<>();
            for (Dish dish : dishRepository.findAllById(setMealRepository.findDishIdBySetMealId(setMeal.getId()))) {
                Integer quantity = setMealRepository.findQuantityBySetMealIdAndDishId(setMeal.getId(), dish.getId());
                dishCount.put(dish.getName(), quantity);
            }
            SetMealDTO setMealDTO = SetMealConverter.convertSetMeal(setMeal);
            setMealDTO.setDishCount(dishCount);
            setMealDTOs.add(setMealDTO);
        }
        return setMealDTOs;
    }

    @Override
    public SetMealDTO updateSetMeal(SetMealDTO setMealDTO) {
        SetMeal setMealInDB = setMealRepository.findById(setMealDTO.getId()).orElseThrow(
                () -> new IllegalArgumentException("setMeal not found")
        );

        // 先处理套餐基本信息的更新
        if (StringUtils.hasLength(setMealDTO.getName()) &&!setMealDTO.getName().equals(setMealInDB.getName())) {
            setMealInDB.setName(setMealDTO.getName());
        }
        if (StringUtils.hasLength(setMealDTO.getCategoryName()) &&!setMealDTO.getCategoryName().equals(setMealInDB.getCategory().getName())) {
            Category category = categoryRepository.findByName(setMealDTO.getCategoryName());
            setMealInDB.setCategory(category);
        }

        // 获取数据库中当前套餐已有的菜品ID集合
        Set<Long> dishIdsInDB = setMealRepository.findDishIdBySetMealId(setMealDTO.getId());

        // 处理菜品数量相关的更新和删除操作
        if (!setMealDTO.getDishCount().isEmpty()) {
            for (String dishName : setMealDTO.getDishCount().keySet()) {
                Dish dish = dishRepository.findByName(dishName);
                if (dish!= null) {
                    if (setMealRepository.findQuantityBySetMealIdAndDishId(setMealDTO.getId(), dish.getId())!= null) {
                        setMealRepository.updateSetMealDishQuantity(setMealDTO.getId(), dish.getId(), setMealDTO.getDishCount().get(dishName));
                    } else {
                        setMealRepository.insertSetMealDish(setMealDTO.getId(), dish.getId(), setMealDTO.getDishCount().get(dishName));
                    }
                    // 如果成功处理了该菜品，从已有的菜品ID集合中移除它的ID
                    dishIdsInDB.remove(dish.getId());
                }
            }
        }

        // 删除剩余在数据库中但不在传过来的JSON中的菜品
        for (Long dishId : dishIdsInDB) {
            setMealRepository.deleteSetMealDish(setMealDTO.getId(), dishId);
        }

        return SetMealConverter.convertSetMeal(setMealRepository.save(setMealInDB));
    }
}
